﻿using System.Collections;
using System.Collections.Generic;
using System;

public static class StaticRandom {

	private static readonly Random random = new Random();

	public static int Next()
	{
		Random obj = StaticRandom.random;
		int result;
		lock (obj)
		{
			result = StaticRandom.random.Next();
		}
		return result;
	}

	public static int Next(int maxValue)
	{
		Random obj = StaticRandom.random;
		int result;
		lock (obj)
		{
			result = StaticRandom.random.Next(maxValue);
		}
		return result;
	}

	public static int Next(int minValue, int maxValue)
	{
		Random obj = StaticRandom.random;
		int result;
		lock (obj)
		{
			result = StaticRandom.random.Next(minValue, maxValue);
		}
		return result;
	}

	public static void NextUnique(ref int lastValue, int minValue, int maxValue)
	{
		Random obj = StaticRandom.random;
		lock (obj)
		{
			for (int i = 0; i < 5; i++)
			{
				int num = StaticRandom.random.Next(minValue, maxValue);
				if (num != lastValue)
				{
					lastValue = num;
					return;
				}
			}
			if (StaticRandom.random.Next(100) > 50)
			{
				lastValue++;
				if (lastValue >= maxValue)
				{
					lastValue = minValue;
				}
			}
			else
			{
				lastValue--;
				if (lastValue < minValue)
				{
					lastValue = maxValue - 1;
				}
			}
		}
	}

	public static bool NextBool()
	{
		return StaticRandom.Next(2) == 0;
	}

	public static void NextBytes(byte[] buffer)
	{
		Random obj = StaticRandom.random;
		lock (obj)
		{
			StaticRandom.random.NextBytes(buffer);
		}
	}

	public static float NextFloat()
	{
		return (float)StaticRandom.NextDouble();
	}

	public static float NextFloat(float maxValue)
	{
		return (float)StaticRandom.NextDouble() * maxValue;
	}

	public static float NextFloat(float minValue, float maxValue)
	{
		return (float)StaticRandom.NextDouble() * (maxValue - minValue) + minValue;
	}

	public static double NextDouble()
	{
		Random obj = StaticRandom.random;
		double result;
		lock (obj)
		{
			result = StaticRandom.random.NextDouble();
		}
		return result;
	}

	public static double NextDouble(double maxValue)
	{
		return StaticRandom.NextDouble() * maxValue;
	}

	public static double NextDouble(double minValue, double maxValue)
	{
		return StaticRandom.NextDouble() * (maxValue - minValue) + minValue;
	}

	public static T NextElement<T>(IList<T> collection)
	{
		return collection[StaticRandom.Next(collection.Count)];
	}
}
